﻿using Common;
using RJCP.IO.Ports;
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace Device
{
    /// <summary>
    /// 直流电源
    /// </summary>
    public class IV_3003T
    {
        static SerialPortStream sp;
        static string receivedData;
        static string StopCode = "\r\n";
        static bool connected;
        static ManualResetEventSlim receivedDataEvent;

        public static void Connect(string port)
        {
            if (connected)
            {
                return;
            }
            sp = new SerialPortStream(port, 9600);
            sp.DataBits = 8;
            sp.StopBits = StopBits.One;
            sp.Parity = Parity.None;

            sp.DataReceived += Sp_DataReceived;

            ManualResetEventSlim openCompletedEvent = new ManualResetEventSlim(false);
            Task.Run(() =>
            {
                sp.Open();
                openCompletedEvent.Set();
            });
            if (!openCompletedEvent.Wait(2000))
            {
                throw new Exception("IV_3003T电源连接超时");
            }

            if (!sp.IsOpen)
            {
                throw new Exception("电源表打开串口失败");
            }
            connected = true;
        }

        public static void Init()
        {
            SetRemote();
            //SetVoltage(12, 0, 0);
            //SetCurrent(1, 0, 0);
            //SetVoltage(12);
            //SetCurrent(1);
            SwitchCh(IV3003T_CH_ENUM.FIRst);
        }

        private static void SendCmd(string cmd)
        {
            Mylog.Debug($"IV_3003T Send[{cmd}]");
            sp?.Write(cmd + StopCode);
        }

        private static string SendCmdAndWaitRespose(string cmd)
        {
            Mylog.Debug($"IV_3003T Send[{cmd}]");

            receivedDataEvent = new ManualResetEventSlim(false);

            sp?.Write(cmd + StopCode);

            if (!receivedDataEvent.Wait(2000))
            {
                throw new Exception("IV_3003T 通信超时");
            }

            return receivedData;
        }

        /// <summary>
        /// 切换远程
        /// </summary>
        public static void SetRemote()
        {
            SendCmd("SYSTem:REMote");
        }

        private static void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPortStream port = sender as SerialPortStream;
            receivedData = port.ReadLine();
            Mylog.Debug($"IV_3003T Received;[{receivedData}]");
            receivedDataEvent.Set();
        }

        //public static void SwitchChStatus(bool ch1Status, bool ch2Status, bool ch3Status)
        //{
        //    SendCmd($"APPly:OUTput {Convert.ToInt32(ch1Status)},{Convert.ToInt32(ch2Status)},{Convert.ToInt32(ch3Status)}");
        //}
        //public static void SetVoltage(double ch1Value = 0, double ch2Value = 0, double ch3Value = 0)
        //{
        //    SendCmd($"APPly:VOLTage {ch1Value},{ch2Value},{ch3Value}");
        //}

        //public static void SetCurrent(double ch1Value = 0, double ch2Value = 0, double ch3Value = 0)
        //{
        //    SendCmd($"APPly:CURRent {ch1Value},{ch2Value},{ch3Value}");
        //}

        /// <summary>
        /// 打开或关闭通道
        /// </summary>
        /// <param name="ch1Status"> true为打开通道1 </param>
        /// <param name="ch2Status"> true为打开通道2 </param>
        /// <param name="ch3Status"> true为打开通道3 </param>
        public static void SwitchCh(IV3003T_CH_ENUM ch)
        {
            var tmp = (int)ch;
            SendCmd($"INSTrument CH{tmp}");
        }

        public static IV3003T_CH_ENUM GetCh()
        {
            string res = SendCmdAndWaitRespose("INSTrument?");

            //res = ParseValues(res).ToString();
            foreach (IV3003T_CH_ENUM item in Enum.GetValues(typeof(IV3003T_CH_ENUM)))
            {
                if (((int)item) == Convert.ToInt32(res.Substring(2)))
                {
                    return item;
                }
            }
            throw new Exception("IV_3003T读取通道异常");
        }

        public static void SetVoltage(double ch1Value = 0)
        {
            SendCmd($"VOLTage {ch1Value}");
        }

        public static void SetCurrent(double ch1Value = 0)
        {
            SendCmd($"CURRent {ch1Value}");
        }

        public static void SetChStatus(int status)
        {
            SendCmd($"OUT{status}");
        }

        public static int GetChStatus()
        {
            var recv = SendCmdAndWaitRespose($"OUTP?");
            return Convert.ToInt32(recv);
        }

        public static void GetVoltage(out double chValue)
        {
            chValue = double.Parse(SendCmdAndWaitRespose("VOLT?"));
        }

        public static void GetCurrent(out double chValue)
        {
            chValue = double.Parse(SendCmdAndWaitRespose("CURR?"));
        }

        private static double ParseValues(string input)
        {
            string pattern = @"设定值\((\d+\.\d+)\)";

            Match match = Regex.Match(input, pattern);

            if (match.Success)
            {
                string value = match.Groups[1].Value;
                if (double.TryParse(value, out double result))
                {
                    return result;
                }
            }
            return -1;
        }
    }
}